package cn.ycq.im.http;

import cn.ycq.im.http.exception.HttpException;
import cn.ycq.im.http.exception.HttpResourceNotFound;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;

public class Routers {

    public static Routers DEFAULT = new Routers();

    private final Map<HttpMethod, Map<String, BiConsumer< HttpRequest, FullHttpResponse>>> handeBinding =
            new ConcurrentHashMap<>();

    public void register(HttpMethod method, String url,  BiConsumer< HttpRequest, FullHttpResponse> handle) {
        Map<String,  BiConsumer< HttpRequest, FullHttpResponse>> consumerMap = handeBinding.computeIfAbsent(method, k -> new ConcurrentHashMap<>());
        consumerMap.put(url, handle);
    }

    public void post(String url,  BiConsumer< HttpRequest, FullHttpResponse> handle) {
        register(HttpMethod.POST, url, handle);
    }

    public void get(String url, BiConsumer< HttpRequest, FullHttpResponse> handle) {
        register(HttpMethod.GET, url, handle);
    }

    public void delete(String url,  BiConsumer< HttpRequest, FullHttpResponse> handle) {
        register(HttpMethod.DELETE, url, handle);
    }

    public void put(String url,  BiConsumer< HttpRequest, FullHttpResponse> handle) {
        register(HttpMethod.PUT, url, handle);
    }

    public void options(String url, BiConsumer< HttpRequest, FullHttpResponse> handle) {
        register(HttpMethod.OPTIONS, url, handle);
    }

    public void findHandleAndInvoke(HttpRequest request, FullHttpResponse response) throws HttpException {
        String uri = request.uri();
        int index = uri.indexOf("?");
        if(index != -1){
            uri = uri.substring(0,index);
        }
        HttpMethod method = request.method();
        Map<String,  BiConsumer< HttpRequest, FullHttpResponse>> consumerMap = handeBinding.get(method);

        BiConsumer< HttpRequest, FullHttpResponse> handle;
        if (consumerMap == null || (handle = consumerMap.get(uri)) == null) {
            throw new HttpResourceNotFound();
        }

        handle.accept(request,response);
    }
}
